package com.fast.framework.core.service.impl;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.log.Log;
import com.fast.framework.config.redis.RedisCache;
import com.fast.framework.config.security.jwt.JwtTokenUtil;
import com.fast.framework.constant.CacheConstants;
import com.fast.framework.core.domain.User;
import com.fast.framework.core.model.LoginBody;
import com.fast.framework.core.service.ILoginService;
import com.fast.framework.core.service.IUserService;
import com.fast.framework.exception.user.*;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;

@Component("loginServiceImpl")
public class LoginServiceImpl implements ILoginService {
    private static final Log log = Log.get(LoginServiceImpl.class);
    @Resource
    private AuthenticationManager authenticationManager;
    @Resource
    private UserDetailsService userDetailsService;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private IUserService userService;
    @Resource
    private JwtTokenUtil jwtTokenUtil;
    @Resource
    private RedisCache redisCache;

    /**
     * 登陆接口
     *
     * @param loginBody 登陆信息
     * @return 登陆结果
     */
    @Override
    public String login(LoginBody loginBody) {
        // 验证码校验
        validateCaptcha(loginBody.getCode(), loginBody.getUuid());

        // 登录前置校验
        // loginPreCheck(username, password);

        //登录
        User loginUser = (User) userDetailsService.loadUserByUsername(loginBody.getUsername());

        //检验用户是否存在
        if (ObjUtil.isEmpty(loginUser)) {
            throw new UserNotExistsException();
        }

        //检验密码
        if (ObjUtil.isEmpty(loginBody.getPassword()) || !passwordEncoder.matches(loginBody.getPassword(), loginUser.getPassword())) {
            throw new UserPasswordNotMatchException();
        }

        //检验账户是否启用
        if (!loginUser.isEnabled()) {
            throw new UserAccountNotEnabledException();
        }

        //更新security登录用户对象
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);

        //记录登录信息
        recordLoginInfo(loginUser.getUserId());

        // 生成token
        String token = jwtTokenUtil.generateToken(loginUser);
        System.out.println("Bearer " + token);
        return token;
    }


    /**
     * 校验验证码
     *
     * @param code 验证码
     * @param uuid 唯一标识
     */
    public void validateCaptcha(String code, String uuid) {
        //验证码的key
        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + ObjectUtil.defaultIfNull(uuid, "");

        //验证码
        String captcha = redisCache.getCacheObject(verifyKey);

        //删除缓存中的值
        redisCache.deleteObject(verifyKey);

        if (captcha == null) {
            throw new CaptchaExpireException();
        }

        if (!code.equalsIgnoreCase(captcha)) {
            throw new CaptchaException();
        }

    }

    /**
     * 记录登录信息
     *
     * @param userId 用户ID
     */
    public void recordLoginInfo(String userId) {
        User loginUser = new User();
        loginUser.setUserId(userId);
        loginUser.setIpaddr("");
        loginUser.setLastLoginTime(new Date());
        userService.updateById(loginUser);
    }
}
